#include <zmq.hpp>
#include <iostream>
#include <sstream>
#include <thread>

static uint64_t s_index = 0;

void subcribe(const char *filter)
{
    zmq::context_t context(1);
    zmq::socket_t subscriber(context, ZMQ_SUB);
    std::string url = "ipc://server.ipc";
    subscriber.connect(url);
    std::cout << "subcribe url: " << url << std::endl;

    subscriber.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter));
    std::cout << "filter: " << filter << std::endl;

    int index;
    for (index = 0; index < 100; index++)
    {
        zmq::message_t msg;
        subscriber.recv(&msg);
        std::string code = std::string((char *)msg.data(), 5);
        std::string data = std::string((char *)msg.data() + 5, msg.size() - 5);
        std::cout << "[recv] code: " << code << ", data: " << data << std::endl;
    }
}

void publish(const char *filter)
{
    zmq::context_t context(2);
    zmq::socket_t publisher(context, ZMQ_PUB);

    std::string url = "ipc://" + std::string(filter) + ".ipc";
    std::cout << "publish url: " << url << std::endl;
    publisher.bind(url); // Not usable on Windows.

    while (1)
    {
        std::string msg = "hello, I am " + std::string(filter) + ", " + std::to_string(s_index++);
        zmq::message_t zmq_msg(msg.data(), msg.size());
        publisher.send(zmq_msg);
        std::cout << "send: " << msg << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

int main(int argc, char *argv[])
{
    const char *filter = (argc > 1) ? argv[1] : "1111A";
    std::thread recvThread(subcribe, filter);
    recvThread.detach();

    std::thread sendThread(publish, filter);
    sendThread.detach();

    while (true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    return 0;
}
